{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2a7c19e0",
   "metadata": {},
   "source": [
    "# Lesson 1: Getting started with RAG\n",
    "\n",
    "\n",
    "Welcome to Lesson 1.\n",
    "\n",
    "To access the `data` file, go to `File` and click on `Open`.\n",
    "\n",
    "I hope you enjoy this course!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c8d2152",
   "metadata": {},
   "source": [
    "### Import required dependencies from npm and load the API key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a5fe0fb9-48f7-48f5-bfd7-b986cbf3628a",
   "metadata": {
    "height": 80
   },
   "outputs": [],
   "source": [
    "import * as mod from \"https://deno.land/std@0.213.0/dotenv/mod.ts\";\n",
    "const keys = await mod.load({export:true}) // read API key from .env\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88051527-5197-438a-975e-30bcb8f8bac8",
   "metadata": {
    "height": 97
   },
   "outputs": [],
   "source": [
    "import { \n",
    "    Document, \n",
    "    VectorStoreIndex, \n",
    "    SimpleDirectoryReader \n",
    "} from \"npm:llamaindex@0.1.8\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94154a7b",
   "metadata": {},
   "source": [
    "### Load our data from a local directory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c65d1c1a-4124-4c99-add0-bd4c497228c0",
   "metadata": {
    "height": 46
   },
   "outputs": [],
   "source": [
    "const documents = await new SimpleDirectoryReader()\n",
    "    .loadData({directoryPath: \"./data\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d779bc04",
   "metadata": {},
   "source": [
    "### Initialize an index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "264bc6f1-172f-4ee1-8f8b-f2095364ec81",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "const index = await VectorStoreIndex.fromDocuments(documents)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02d3e918",
   "metadata": {},
   "source": [
    "### Create a query engine \n",
    "\n",
    "This convenience function combines several components:\n",
    "- Retriever\n",
    "- Postprocessing\n",
    "- Synthesizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6daa7e7e-4fff-4a76-937a-6d260fc10f2c",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "const queryEngine = index.asQueryEngine()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68c49ed7",
   "metadata": {},
   "source": [
    "### Let's ask a question!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "41e43a70-0e6d-4cbd-8773-84d2e0953a55",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "const response = await queryEngine.query({\n",
    "    query: \"What did the author do in college?\"\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a730b2ee-b2bd-4a11-ae0c-04b5b27ba642",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "console.log(response.toString())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "115b50b7",
   "metadata": {},
   "source": [
    "### But what just happened? let's break it down!\n",
    "\n",
    "You need an:\n",
    "- LLM to answer questions\n",
    "- embedding model to encode them"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5d8b22bd-2268-49b3-81f6-5af5cc10b8d9",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "import * as llamaIndex from \"npm:llamaindex@0.1.8\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2f4f212-3fe3-42f9-9ad9-5a7ba39818bd",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "let customLLM = new llamaIndex.OpenAI()\n",
    "let customEmbedding = new llamaIndex.OpenAIEmbedding()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6e508f3",
   "metadata": {},
   "source": [
    " Let's put the LLM and the embedding model into a `ServiceContext` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "09490334-fc73-4b9d-910f-55077485675f",
   "metadata": {
    "height": 97
   },
   "outputs": [],
   "source": [
    "let customServiceContext = new llamaIndex.serviceContextFromDefaults({\n",
    "    llm: customLLM,\n",
    "    embedModel: customEmbedding\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d663eebf",
   "metadata": {},
   "source": [
    "### Let's make our own prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6067f78-8231-4897-9337-ff93ec1fccd4",
   "metadata": {
    "height": 199
   },
   "outputs": [],
   "source": [
    "let customQaPrompt = function({context = \"\", query = \"\"}) {\n",
    "    return `Context information is below.\n",
    "        ---------------------\n",
    "        ${context}\n",
    "        ---------------------\n",
    "        Given the context information, answer the query.\n",
    "        Include a random fact about whales in your answer.\\\n",
    "        The whale fact can come from your training data.\n",
    "        Query: ${query}\n",
    "        Answer:`\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4708677",
   "metadata": {},
   "source": [
    "You need a `ResponseBuilder` that uses our prompt and our service context."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4441c6b-02f8-4a48-b564-42dcb4f824cc",
   "metadata": {
    "height": 97
   },
   "outputs": [],
   "source": [
    "let customResponseBuilder = new llamaIndex.SimpleResponseBuilder(\n",
    "    customServiceContext,\n",
    "    customQaPrompt\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04956f00",
   "metadata": {},
   "source": [
    "The `responseBuilder` goes to a `synthesizer`, which also needs a service context."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4045a04d-ca0e-4ef5-b436-ab39f649d5a0",
   "metadata": {
    "height": 80
   },
   "outputs": [],
   "source": [
    "let customSynthesizer = new llamaIndex.ResponseSynthesizer({\n",
    "    responseBuilder: customResponseBuilder,\n",
    "    serviceContext: customServiceContext\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdae0ca4",
   "metadata": {},
   "source": [
    "You also need a `retriever`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c08ce1b0-d008-4fdb-8bd2-888d78324e19",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "let customRetriever = new llamaIndex.VectorIndexRetriever({\n",
    "    index\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9c9fe8d",
   "metadata": {},
   "source": [
    "The `synthesizer` and the `retriever` go to our query engine:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "405bf5e1-15c6-4a8f-bbed-45f8f559bb2f",
   "metadata": {
    "height": 80
   },
   "outputs": [],
   "source": [
    "let customQueryEngine = new llamaIndex.RetrieverQueryEngine(\n",
    "    customRetriever,\n",
    "    customSynthesizer\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22c89ca2",
   "metadata": {},
   "source": [
    "### Let's check the response!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f42ca94b-0270-41d9-af24-31d161fb74fd",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "let response2 = await customQueryEngine.query({\n",
    "    query: \"What does the author think of college?\"\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4d0a5140-126b-4ee5-baf6-ff49f022936a",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "console.log(response2.toString())"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
